home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / cxe103.zip / CXF.C < prev    next >
C/C++ Source or Header  |  1992-08-03  |  7KB  |  254 lines

  1. /*
  2.    Copyright (c) 1990-1992 Eugene Nelson
  3.  
  4.    This program demonstrates the suggested usage of the Cx Data Compression
  5.    Library.  It will compress and decompress a file of any size, containing
  6.    any type of data.  The compressed data is stored with 16 bit CRC's to
  7.    help in detecting errors.  It stores the file as blocks of data which
  8.    have the following form:              
  9.  
  10.       BLOCK
  11.       ----------------------------------------------------
  12.       2 bytes - size of uncompressed block (USIZE)
  13.       2 bytes - size of compressed block   (CSIZE)
  14.       2 bytes - 16 bit CRC                 (CRC)
  15.       CSIZE   - data                       (DATA)
  16.       ----------------------------------------------------
  17.  
  18.    If a block cannot be compressed, the original data is stored, and
  19.    USIZE and CSIZE will be the same.  The CRC is computed on the
  20.    compressed data.
  21.  
  22.    2 bytes of 0 are stored at the end of the compressed file to indicate
  23.    the end of file.
  24. */
  25.  
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <io.h>
  29. #include <fcntl.h>
  30. #include <sys\types.h>
  31. #include <sys\stat.h>
  32.  
  33. #include "cx.h"
  34.  
  35. /*-------------------------------------------------------------------------*/
  36. void  USAGE(void)
  37. {
  38.    printf("usage: cxf 1|2|3|t|d infile outfile\n");
  39.    printf("   1|2|3   - compress infile to outfile using method 1,2 or 3\n");
  40.    printf("   d       - decompress infile to outfile\n");
  41.    printf("   t       - test integrity of infile\n\n");
  42.    printf("   Examples:\n");
  43.    printf("      cxf 1 cxf.exe x.x\n");
  44.    printf("      cxf t x.x\n");
  45.    printf("      cxf d x.x y.y\n");
  46.    exit (0);
  47. }
  48.  
  49. /*-------------------------------------------------------------------------*/
  50. void  QUIT(char *s)
  51. {
  52.    printf("\n%s\n", s);
  53.    exit (0);
  54. }
  55.  
  56. /*-------------------------------------------------------------------------*/
  57. #define MALLOC(p,n)  {if ((p = malloc(n)) == NULL) QUIT ("insufficient memory");}
  58. #define FREE(p)      free(p)
  59. #define CREATE(s)    open(s, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE)
  60. #define OPEN(s)      open(s, O_RDWR|O_BINARY, 0)
  61. #define WRITE(f,b,n) {if (write(f, b, n) != n) QUIT ("could not write");}
  62. #define READ(f,b,n)  {if (read(f, b, n) != n) QUIT ("could not read");}
  63. #define CLOSE(f)     {if (close(f) != 0) QUIT ("could not close");}
  64.  
  65. /*-------------------------------------------------------------------------*/
  66. void  file_compress(char *dst, char *src, CXINT method, CXINT size)
  67. {
  68.    int      ifile, ofile;
  69.    long     ifilesize, ofilesize;
  70.    CXINT    j, k, crc;
  71.    CXBUFF   ibuff, obuff, tbuff;
  72.  
  73.    if ((ifile = OPEN(src)) == -1)
  74.       QUIT ("could not open ifile");
  75.  
  76.    unlink(dst);
  77.    if ((ofile = CREATE(dst)) == -1)
  78.       QUIT ("could not open ofile");
  79.  
  80.    MALLOC(ibuff, size);
  81.    MALLOC(obuff, size+CX_SLOP);
  82.    MALLOC(tbuff, CX_C_MAXTEMP);
  83.  
  84.    ifilesize = ofilesize = 0;
  85.    while (1)
  86.    {
  87.       printf(".");
  88.  
  89.       j = read(ifile, ibuff, size);
  90.       WRITE(ofile, &j, CXINTSIZE);
  91.       ifilesize += j;
  92.       ofilesize += CXINTSIZE;
  93.       if (j == 0)
  94.          break;
  95.  
  96.       k = CX_COMPRESS(method, obuff, size, ibuff, j, tbuff, CX_C_MAXTEMP);
  97.       switch (k)
  98.       {
  99.          case CX_ERR_METHOD:
  100.             QUIT("unknown or unsupported method, evaluation version only allows CX_MEHTOD1");
  101.  
  102.          case CX_ERR_BUFFSIZE:
  103.             QUIT("invallid input or output buffer size");
  104.  
  105.          case CX_ERR_TEMPSIZE:
  106.             QUIT("invalid temporary buffer size");
  107.       }
  108.  
  109.       WRITE(ofile, &k, CXINTSIZE);
  110.  
  111.       if (k == j)    /* if block could not be compressed */
  112.       {
  113.          crc = CX_CRC(ibuff, k);
  114.          WRITE(ofile, &crc, sizeof(crc));
  115.          WRITE(ofile, ibuff, k)
  116.       }
  117.       else
  118.       {
  119.          crc = CX_CRC(obuff, k);
  120.          WRITE(ofile, &crc, sizeof(crc));
  121.          WRITE(ofile, obuff, k)
  122.       }
  123.  
  124.       ofilesize += CXINTSIZE+sizeof(crc)+k;
  125.    }
  126.  
  127.    FREE(ibuff);
  128.    FREE(obuff);
  129.    FREE(tbuff);
  130.  
  131.    CLOSE(ifile);
  132.    CLOSE(ofile);
  133.  
  134.    printf("\n");
  135.    printf("Insize:   %10ld\n", ifilesize);
  136.    printf("Outsize:  %10ld\n", ofilesize);
  137.    if (ifilesize != 0)
  138.       printf("Percent:  %10d", (ofilesize*100)/ifilesize);
  139. }
  140.  
  141. /*-------------------------------------------------------------------------*/
  142. void  file_decompress(char *dst, char *src)
  143. {
  144.    int      ifile, ofile;
  145.    CXINT    j, k, crc;
  146.    CXBUFF   ibuff, obuff, tbuff;
  147.  
  148.    if ((ifile = OPEN(src)) == -1)
  149.       QUIT ("could not open ifile");
  150.  
  151.    if (dst != NULL)
  152.    {
  153.       unlink(dst);
  154.       if ((ofile = CREATE(dst)) == -1)
  155.          QUIT ("could not open ofile");
  156.    }
  157.  
  158.    MALLOC(ibuff, CX_MAX_BUFFER+CX_SLOP);
  159.    MALLOC(obuff, CX_MAX_BUFFER);
  160.    MALLOC(tbuff, CX_D_MINTEMP);
  161.  
  162.    while (1)
  163.    {
  164.       printf(".");
  165.  
  166.       READ(ifile, &j, CXINTSIZE);
  167.       if (j == 0)
  168.          break;
  169.  
  170.       READ(ifile, &k, CXINTSIZE);
  171.       READ(ifile, &crc, sizeof(crc));
  172.       READ(ifile, ibuff, k);
  173.  
  174.       if (CX_CRC(ibuff, k) != crc)
  175.          QUIT ("CRC error");
  176.  
  177.       if (j == k)    /* if block is not compressed */
  178.       {
  179.          if (dst != NULL)
  180.             WRITE(ofile, ibuff, j);
  181.       }
  182.       else
  183.       {
  184.          k = CX_DECOMPRESS(obuff, CX_MAX_BUFFER, ibuff, k, tbuff, CX_D_MINTEMP);
  185.          switch (k)
  186.          {
  187.             case CX_ERR_INVALID:
  188.                QUIT("data being compressed is corrupt, or was not compressed with Cx.");
  189.  
  190.             case CX_ERR_METHOD:
  191.                QUIT("unknown or unsupported method, evaluation version only allows CX_MEHTOD1");
  192.  
  193.             case CX_ERR_BUFFSIZE:
  194.                QUIT("End of Data symbol not found");
  195.    
  196.             case CX_ERR_TEMPSIZE:
  197.                QUIT("invalid temporary buffer size");
  198.          }
  199.  
  200.          if (k != j)
  201.             QUIT("data being compressed is corrupt, or was not compressed with Cx.");
  202.  
  203.          if (dst != NULL)
  204.             WRITE(ofile, obuff, j);
  205.       }
  206.    }
  207.  
  208.    FREE(ibuff);
  209.    FREE(obuff);
  210.    FREE(tbuff);
  211.  
  212.    CLOSE(ifile);
  213.    if (dst != NULL)
  214.       CLOSE(ofile);
  215. }
  216.  
  217. /*-------------------------------------------------------------------------*/
  218. void  main(int argc, char *argv[])
  219. {
  220.    int   ch;
  221.  
  222.    if (argc < 4)
  223.    {
  224.       if (argc < 3)
  225.          USAGE();
  226.  
  227.       ch = toupper(argv[1][0]);
  228.  
  229.       if (ch == 'T')
  230.          file_decompress(NULL, argv[2]);
  231.       else if (ch == 'R')
  232.          file_decompress(NULL, argv[2]);
  233.       else
  234.          USAGE();
  235.    }
  236.    else
  237.    {
  238.       ch = toupper(argv[1][0]);
  239.  
  240.       if (ch == '1')
  241.          file_compress(argv[3], argv[2], CX_METHOD1, CX_MAX_BUFFER);
  242.       else if (ch == '2')
  243.          file_compress(argv[3], argv[2], CX_METHOD2, CX_MAX_BUFFER);
  244.       else if (ch == '3')
  245.          file_compress(argv[3], argv[2], CX_METHOD2, CX_MAX_BUFFER);
  246.       else if (ch == 'D')
  247.          file_decompress(argv[3], argv[2]);
  248.       else
  249.          USAGE();
  250.    }
  251.  
  252.    QUIT ("Ok");
  253. }
  254.